import 'package:flutter/material.dart';
import 'package:flutter_ume_kit_mock/widgets/mock_inspector.dart';
import 'package:fluttertoast/fluttertoast.dart';

import 'package:flutter_ume_kit_mock/data/mock_config_manager.dart';
import 'package:flutter_ume_kit_mock/data/model/mock_history.dart';
import 'package:flutter_ume_kit_mock/data/model/mock.dart';
import 'package:flutter_ume_kit_mock/data/model/case.dart';
import 'package:flutter_ume_kit_mock/widgets/case_item.dart';
import 'package:flutter_ume_kit_mock/widgets/mock_detail.dart';
import 'package:flutter_ume_kit_mock/widgets/mock_history_page.dart';
import 'package:flutter_ume_kit_mock/widgets/mock_item.dart';

typedef MockClickListener = void Function(Mock mock);

class MockState extends State<MockInspector> with TickerProviderStateMixin {
  final Set<String> _hiddenModules = {};
  Mock? _detailMock;
  bool filterEnables = false;
  bool showHistory = false;

  final ButtonStyle _bottomButtonStyle = ButtonStyle(
      shadowColor: MaterialStateProperty.all(Colors.lightBlue.withOpacity(0.5)),
      backgroundColor: MaterialStateProperty.all(Colors.white),
      foregroundColor: MaterialStateProperty.all(Colors.black),
      shape: MaterialStateProperty.all(const CircleBorder()));

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        //列表
        Column(
          children: [
            const ColoredBox(
                color: Colors.black54,
                child: SizedBox(height: 120, width: double.infinity)),
            Expanded(
              child: ColoredBox(
                  color: Colors.white,
                  child: Material(child: buildConfigChangeListener(context))),
            ),
          ],
        ),
        Positioned(
          bottom: 0,
          left: 0,
          right: 0,
          child: Container(
            height: 80,
            decoration: const BoxDecoration(
                gradient: LinearGradient(
                    begin: Alignment.topLeft,
                    end: Alignment.bottomLeft,
                    stops: [
                  0,
                  0.5,
                  1
                ],
                    colors: [
                  Color(0x00FFFFFF),
                  Color(0xDDFFFFFF),
                  Color(0xFFFFFFFF)
                ])),
          ),
        ),
        Positioned(
          bottom: 10,
          left: 0,
          child: ValueListenableBuilder<Set<String>>(
              valueListenable: MockConfigManager.enableSetNotifier,
              builder: (context, enableSet, child) {
                if (enableSet.isEmpty) {
                  filterEnables = false;
                }
                return ValueListenableBuilder<List<MockHistory>>(
                    valueListenable: MockConfigManager.mockHistoryNotifier,
                    builder: (context, mockHistory, child) {
                      return Row(
                        children: [
                          //刷新按钮
                          _buildRefreshButton(),
                          //查看已开启按钮
                          if (enableSet.isNotEmpty) _buildEnablesButton(),
                          //查看历史按钮
                          if (mockHistory.isNotEmpty)
                            _buildHistoryButton(mockHistory.length),
                        ],
                      );
                    });
              }),
        ),
        //mock历史
        if (showHistory)
          MockHistoryPage(
            onDismiss: () {
              setState(() {
                showHistory = false;
              });
            },
            onMockClick: (mock) {
              setState(() {
                _detailMock = mock;
              });
            },
          ),
        //mock详情
        if (_detailMock != null)
          MockDetail(_detailMock!, onDismiss: () {
            setState(() {
              _detailMock = null;
            });
          }),
      ],
    );
  }

  @override
  void dispose() {
    super.dispose();
    animationController.dispose();
  }

  Widget buildConfigChangeListener(BuildContext context) {
    return ValueListenableBuilder<List<MockCase>>(
        valueListenable: MockConfigManager.caseListNotifier,
        builder: (context, caseList, child) {
          return ValueListenableBuilder<List<Mock>>(
              valueListenable: MockConfigManager.mockListNotifier,
              builder: (context, mockList, child) {
                Map<String, List<dynamic>> moduleMap =
                    _groupByModule(caseList, mockList);
                List<dynamic> flatList = _flatGroupMap(moduleMap);
                if (_hiddenModules.isEmpty && flatList.length > 10) {
                  //如果>10条，全部折叠
                  moduleMap.forEach((key, value) {
                    _hiddenModules.add(key);
                  });
                }
                return _buildConfigList(context, flatList, moduleMap);
              });
        });
  }

  ///主列表
  Widget _buildConfigList(BuildContext context, List<dynamic> moduleFlatList,
      Map<String, List<dynamic>> moduleMap) {
    return ListView.builder(
        itemBuilder: (context, index) {
          dynamic item = moduleFlatList[index];
          switch (item.runtimeType) {
            case String:
              return _buildModuleName(context, item, moduleMap);
            case MockCase:
              var mockCase = item as MockCase;
              if (_hiddenModules.contains(mockCase.fields?.module)) {
                return const SizedBox.shrink();
              }
              return CaseItem(item, _showMockDetail);
            case Mock:
              var mock = item as Mock;
              if (_hiddenModules.contains(mock.fields?.module)) {
                return const SizedBox.shrink();
              }
              return MockItem(item, _showMockDetail);
            default:
              return const SizedBox.shrink();
          }
        },
        padding: const EdgeInsets.only(bottom: 60),
        itemCount: moduleFlatList.length);
  }

  void _showMockDetail(Mock mock) {
    setState(() {
      _detailMock = mock;
    });
  }

  ///模块名称，显示（开启数量/总数量）
  Widget _buildModuleName(
      BuildContext context, String name, Map<String, List<dynamic>> moduleMap) {
    var list = moduleMap[name] ?? [];
    int enableCount = 0;
    for (var element in list) {
      if (element is MockCase && element.enable ||
          element is Mock && element.enable) {
        enableCount++;
      }
    }
    bool isHidden = _hiddenModules.contains(name);
    return Ink(
      decoration: BoxDecoration(
          color: Colors.blue.shade200,
          border: Border(bottom: BorderSide(color: Colors.grey.shade300))),
      child: InkWell(
        overlayColor: MaterialStateProperty.all(const Color(0x12000000)),
        child: Container(
            padding: const EdgeInsets.only(left: 16, top: 10, bottom: 10),
            child: Text(
              "$name ($enableCount/${list.length})  ${isHidden ? "🙈" : ""}",
              style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
            )),
        onTap: () {
          //点击模块显示/隐藏
          setState(() {
            if (isHidden) {
              _hiddenModules.remove(name);
            } else {
              _hiddenModules.add(name);
            }
          });
        },
      ),
    );
  }

  ///mock历史
  Widget _buildHistoryButton(int historyCount) {
    return ElevatedButton(
      style: _bottomButtonStyle,
      child: Stack(
        clipBehavior: Clip.none,
        children: [
          const Padding(
            padding: EdgeInsets.all(10),
            child: Icon(
              Icons.history,
              size: 30,
            ),
          ),
          Positioned(
              right: 0,
              child: Container(
                decoration: const BoxDecoration(
                    color: Colors.blueGrey,
                    borderRadius: BorderRadius.all(Radius.circular(100))),
                padding: const EdgeInsets.only(left: 4, right: 4),
                child: Text(
                  historyCount.toString(),
                  style: const TextStyle(color: Colors.white, fontSize: 12),
                ),
              ))
        ],
      ),
      onPressed: () {
        setState(() {
          showHistory = true;
        });
      },
    );
  }

  ///显示已开启按钮
  Widget _buildEnablesButton() {
    return ElevatedButton(
      style: _bottomButtonStyle,
      child: Padding(
        padding: const EdgeInsets.all(10),
        child: Icon(
          filterEnables ? Icons.list : Icons.checklist,
          size: 30,
        ),
      ),
      onPressed: () {
        setState(() {
          filterEnables = !filterEnables;
        });
      },
    );
  }

  ///刷新动画
  late AnimationController animationController =
      AnimationController(vsync: this, duration: const Duration(milliseconds: 600));

  late Animation<double> rotateAnimation =
      Tween<double>(begin: 0, end: 1).animate(animationController);

  bool refreshing = false;

  ///刷新按钮
  Widget _buildRefreshButton() {
    return ElevatedButton(
      style: _bottomButtonStyle,
      child: Padding(
        padding: const EdgeInsets.all(10),
        child: RotationTransition(
          turns: rotateAnimation,
          child: const Icon(
            Icons.refresh,
            size: 30,
          ),
        ),
      ),
      onPressed: () async {
        if (refreshing) {
          return;
        }
        refreshing = true;
        animationController.repeat();
        bool success = await MockConfigManager.fetchMockConfig(
            widget.dio, widget.feishuAppId, widget.feishuAppSecret);
        Fluttertoast.showToast(
            msg: success ? "刷新成功" : "刷新失败", gravity: ToastGravity.CENTER);
        refreshing = false;
        animationController.forward();
      },
    );
  }

  ///将模块名、case、mock混到一个list中，后续根据类型渲染
  Map<String, List<dynamic>> _groupByModule(
      List<MockCase> caseList, List<Mock> mockList) {
    Map<String, List<dynamic>> moduleMap = {};
    for (var element in caseList) {
      String module = element.fields?.module ?? "";
      if (filterEnables && !element.enable) {
        continue;
      }
      List<dynamic> list = moduleMap[module] ?? [];
      list.add(element);
      moduleMap[module] = list;
    }
    for (var element in mockList) {
      String module = element.fields?.module ?? "";
      if (filterEnables && !element.enable) {
        continue;
      }
      List<dynamic> list = moduleMap[module] ?? [];
      list.add(element);
      moduleMap[module] = list;
    }
    return moduleMap;
  }

  List<dynamic> _flatGroupMap(Map<String, List<dynamic>> moduleMap) {
    List<dynamic> list = [];
    moduleMap.forEach((key, value) {
      if (value.isNotEmpty) {
        list.add(key);
        for (var element in value) {
          list.add(element);
        }
      }
    });
    return list;
  }
}
